<template>
  <Transition
    enter-active-class="transition duration-300 ease-out"
    enter-from-class="transform opacity-0 translate-y-2"
    enter-to-class="transform opacity-100 translate-y-0"
    leave-active-class="transition duration-200 ease-in"
    leave-from-class="transform opacity-100 translate-y-0"
    leave-to-class="transform opacity-0 translate-y-2"
  >
    <div
      v-if="visible"
      class="flex items-center gap-3 min-w-[300px] max-w-[400px] p-4 rounded-lg shadow-lg backdrop-blur-sm border"
      :class="[typeClass, standalone ? positionClass : '']"
    >
      <div class="flex-shrink-0">
        <div
          class="w-8 h-8 rounded-full flex items-center justify-center"
          :class="iconWrapperClass"
        >
          <svg
            class="w-5 h-5"
            viewBox="0 0 24 24"
            fill="none"
            stroke="currentColor"
            stroke-width="2"
            stroke-linecap="round"
            stroke-linejoin="round"
          >
            <template v-if="type === 'success'">
              <path d="M22 11.08V12a10 10 0 1 1-5.93-9.14" />
              <polyline points="22 4 12 14.01 9 11.01" />
            </template>
            <template v-else-if="type === 'error'">
              <circle cx="12" cy="12" r="10" />
              <line x1="15" y1="9" x2="9" y2="15" />
              <line x1="9" y1="9" x2="15" y2="15" />
            </template>
            <template v-else-if="type === 'warning'">
              <path
                d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"
              />
              <line x1="12" y1="9" x2="12" y2="13" />
              <line x1="12" y1="17" x2="12.01" y2="17" />
            </template>
            <template v-else>
              <circle cx="12" cy="12" r="10" />
              <line x1="12" y1="16" x2="12" y2="12" />
              <line x1="12" y1="8" x2="12.01" y2="8" />
            </template>
          </svg>
        </div>
      </div>
      <div class="flex-grow">
        <p class="text-sm font-medium break-all">{{ message }}</p>
      </div>
      <button
        @click="close"
        class="flex-shrink-0 opacity-70 hover:opacity-100 transition-opacity"
      >
        <svg
          class="w-4 h-4"
          viewBox="0 0 24 24"
          fill="none"
          stroke="currentColor"
          stroke-width="2"
          stroke-linecap="round"
          stroke-linejoin="round"
        >
          <line x1="18" y1="6" x2="6" y2="18" />
          <line x1="6" y1="6" x2="18" y2="18" />
        </svg>
      </button>
    </div>
  </Transition>
</template>

<style scoped>
/* 移除之前的动画样式，因为我们现在使用 Tailwind 的类来控制动画 */
</style>

<script setup lang="ts">
import { ref, computed, onMounted, onBeforeUnmount } from "vue";

export type ToastType = "success" | "error" | "info" | "warning";
export type ToastPosition =
  | "top-left"
  | "top-center"
  | "top-right"
  | "bottom-left"
  | "bottom-center"
  | "bottom-right";

const props = withDefaults(
  defineProps<{
    message: string;
    type?: ToastType;
    duration?: number;
    position?: ToastPosition;
    standalone?: boolean;
  }>(),
  {
    type: "info",
    duration: 3000,
    position: "top-center",
    standalone: true,
  },
);

const emit = defineEmits<{
  (e: "destroy"): void;
  (e: "close"): void;
}>();

const visible = ref(false);
let hideTimer: number | null = null;

const typeClasses: Record<ToastType, string> = {
  success: "bg-success/10 border-success/20 text-success-content",
  error: "bg-error/10 border-error/20 text-error-content",
  info: "bg-info/10 border-info/20 text-info-content",
  warning: "bg-warning/10 border-warning/20 text-warning-content",
};

const iconWrapperClasses: Record<ToastType, string> = {
  success: "bg-success/20",
  error: "bg-error/20",
  info: "bg-info/20",
  warning: "bg-warning/20",
};

const positionClasses: Record<ToastPosition, string> = {
  "top-left": "fixed top-4 left-4 z-50",
  "top-center": "fixed top-4 left-1/2 -translate-x-1/2 z-50",
  "top-right": "fixed top-4 right-4 z-50",
  "bottom-left": "fixed bottom-4 left-4 z-50",
  "bottom-center": "fixed bottom-4 left-1/2 -translate-x-1/2 z-50",
  "bottom-right": "fixed bottom-4 right-4 z-50",
};

const typeClass = computed(() => typeClasses[props.type]);
const iconWrapperClass = computed(() => iconWrapperClasses[props.type]);
const positionClass = computed(() => positionClasses[props.position]);

const close = () => {
  visible.value = false;
  if (hideTimer) {
    clearTimeout(hideTimer);
  }
  emit("close");
  setTimeout(() => emit("destroy"), 200);
};

onMounted(() => {
  visible.value = true;
  hideTimer = window.setTimeout(close, props.duration);
});

onBeforeUnmount(() => {
  if (hideTimer) {
    clearTimeout(hideTimer);
  }
});

defineExpose({
  close,
});
</script>
